package br.com.intelsys.basics.servlet;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import br.com.intelsys.basics.utils.MimeTypeExtractor;

/**
 * Servlet para interceptar recursos estaticos.<br/>
 * <br/>
 * 
 * Util para sites com URL's dinamicas, normalmente usados em SEO.<br/>
 * <br/>
 * 
 * Declare este servlet em seu web.xml da seguinte forma:<br/>
 * 
 * <pre>
 * 	&lt;servlet&gt;
 * 	&lt;servlet-name&gt;staticResource&lt;/servlet-name&gt;
 * 	&lt;servlet-class&gt;br.com.intelsys.basics.servlet.StaticResourceServlet&lt;/servlet-class&gt;
 * 	&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
 * &lt;/servlet&gt;
 * &lt;servlet-mapping&gt;
 * 	&lt;servlet-name&gt;staticResource&lt;/servlet-name&gt;
 * 	&lt;url-pattern&gt;/static/*&lt;/url-pattern&gt;
 * &lt;/servlet-mapping&gt;
 * </pre>
 * 
 * <br/>
 * <br/>
 * 
 * Onde "/static" eh o diretorio que contem seus recursos estaticos como
 * JavaScripts, Imagens, CSSs, etc.
 * 
 * @author Patrick Givisiez
 * 
 */
public class StaticResourceServlet extends HttpServlet {
	private static final long serialVersionUID = -2280429686528811879L;
	private static final String EMPTY = "";
	private static final String PATH_PARENT = "\\.\\./";
	private static final String PATH_ROOT = "/";
	private static final String CONTENT_TYPE_DEFAULT = "application/octet-stream";
	private static String realPath;
	private static Logger log = Logger.getLogger(StaticResourceServlet.class);

	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			String path = getFilePath(req);
			DataInputStream dis = getDataInputStream(path);
			byte[] b = new byte[1];
			while (dis.available() != 0) {
				dis.read(b);
				resp.getOutputStream().write(b);
			}
			resp.setContentType(getContentType(path));
			dis.close();
		} catch (FileNotFoundException e) {
			resp.setStatus(404);
		}
	}

	private String getContentType(String path) {
		String ct = MimeTypeExtractor.getContentType(path);
		if (CONTENT_TYPE_DEFAULT.equals(ct)) {
			String[] extArr = path.split("\\.");
			if (extArr.length > 1) {
				String ext = extArr[extArr.length - 1].toLowerCase();
				if ("css".equals(ext)) {
					return "text/css";
				}
			}
		}
		return ct;
	}

	private DataInputStream getDataInputStream(String path) throws FileNotFoundException {
		return new DataInputStream(new FileInputStream(path));
	}

	private String getRealPath(HttpServletRequest req) {
		if (realPath == null) {
			realPath = getServletContext().getRealPath(PATH_ROOT);
		}
		return realPath;
	}

	private String getFilePath(HttpServletRequest req) {
		StringBuilder sb = new StringBuilder(getRealPath(req));
		sb.append(req.getRequestURI().substring(1).replaceAll(PATH_PARENT, EMPTY));
		return sb.toString();
	}

}
